import psutil  # 用于获取系统信息（CPU、内存、磁盘等）
import socket
import requests  # 用于发送HTTP请求
from datetime import datetime  # 用于获取当前时间

# API配置 - 定义监控数据上报的API端点
cpu_url = "http://192.168.88.1:8000/v1/cpu"  # CPU监控数据上报地址
mem_url = "http://192.168.88.1:8000/v1/mem"  # 内存监控数据上报地址
disk_url = "http://192.168.88.1:8000/v1/disk"  # 磁盘监控数据上报地址

# 常量定义
MB = 1024 * 1024  # 1MB的字节数，用于字节到MB的转换
skip_fs = {'tmpfs', 'devtmpfs', 'squashfs'}  # 需要跳过的文件系统类型集合
name = socket.gethostname()
time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

def send_cpu():
    """
    收集并发送CPU使用率信息
    """

    # 获取每个CPU核心的使用率，percpu=True表示获取每个核心的使用率，interval=1表示采样间隔1秒
    for i, p in enumerate(psutil.cpu_percent(percpu=True, interval=1)):
        try:
            # 构造POST请求，发送JSON格式的CPU使用数据
            r = requests.post(cpu_url, json={
                "hostname": name,  # 主机名
                "date": time,  # 当前时间
                "cpu_core": f"cpu{i}",  # CPU核心编号
                "cpu_used": f"{p:.1f}%",  # CPU使用率，保留1位小数
                "cpu_free": f"{100 - p:.1f}%"  # CPU空闲率，保留1位小数
            })
            # 打印提交结果，根据状态码判断是否成功
            print(f"CPU cpu{i} 提交{'成功' if r.status_code == 200 else '失败'}")
        except Exception as e:
            # 捕获并打印异常信息
            print(f"CPU cpu{i} 错误：{type(e).__name__}")


def send_mem():
    """
    收集并发送内存使用信息
    """
    try:
        # 获取内存使用信息
        m = psutil.virtual_memory()
        # 构造POST请求，发送JSON格式的内存使用数据
        r = requests.post(mem_url, json={
            "hostname": name,  # 主机名
            "date": time,  # 当前时间
            "used": m.used // MB,  # 已用内存(MB)，整数
            "free": m.free // MB,  # 空闲内存(MB)，整数
            "total": m.total // MB,  # 总内存(MB)，整数
            "used_percent": f"{m.percent:.1f}%"  # 内存使用百分比，保留1位小数
        })
        # 打印提交结果
        print(f"内存 提交{'成功' if r.status_code == 200 else '失败'}")
    except Exception as e:
        # 捕获并打印异常信息
        print(f"内存 错误：{type(e).__name__}")


def send_disk():
    """
    收集并发送磁盘使用信息
    """

    # 遍历所有磁盘分区
    for d in psutil.disk_partitions():
        # 跳过特定类型的文件系统
        if d.fstype.lower() in skip_fs:
            continue
        try:
            # 获取磁盘使用情况
            u = psutil.disk_usage(d.mountpoint)
            # 构造POST请求，发送JSON格式的磁盘使用数据
            r = requests.post(disk_url, json={
                "hostname": name,  # 主机名
                "date": time,  # 当前时间
                "f_type": d.fstype,  # 文件系统类型
                "used": round(u.used / MB, 1),  # 已用空间(MB)，保留1位小数
                "free": round(u.free / MB, 1),  # 空闲空间(MB)，保留1位小数
                "total": round(u.total / MB, 1),  # 总空间(MB)，保留1位小数
                "used_percent": f"{u.percent:.1f}%",  # 使用百分比，保留1位小数
                "mountpoint": d.mountpoint.replace('\\', '/')  # 挂载点，统一使用/分隔符
            })
            # 打印提交结果
            print(f"磁盘 {d.mountpoint} 提交{'成功' if r.status_code == 200 else '失败'}")
        except Exception as e:
            # 捕获并打印异常信息
            print(f"磁盘 {d.mountpoint} 错误：{type(e).__name__}")


if __name__ == '__main__':
    # 主程序入口
    send_cpu()  # 发送CPU信息
    send_mem()  # 发送内存信息
    send_disk()  # 发送磁盘信息